/*
* 读写者问题写者优先解决方案
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sem_w, sem_r;
sem_t sem_rc;
int rc = 0;

void * reader(void * arg){
    printf("add a reader.\n");
    int count = 0;
    while(count < 3){
        sleep(rand()%3);
        sem_wait(&sem_r);

        sem_wait(&sem_rc);
        if(0 == rc){
            sem_wait(&sem_w);
        }
        rc++;
        sem_post(&sem_rc);
        sem_post(&sem_r);

        printf("reading ...\n");
        sleep(0.5);

        sem_wait(&sem_rc);
        rc--;
        if(0 == rc){
            sem_post(&sem_w);
        }
        sem_post(&sem_rc);
        count++;
    }
    count++;
}

void * writter(void * arg){
    printf("add a reader.\n");
    int count = 0;
    while(count < 3){
        sleep(rand()%3);

        sem_wait(&sem_r);
        sem_wait(&sem_w);

        printf("writting ...\n");
        sleep(0.5);
        sem_post(&sem_w);
        sem_post(&sem_r);

        count++;
    }
}

int main(){
    sem_init(&sem_r, 0, 1);
    sem_init(&sem_w, 0, 1);
    sem_init(&sem_rc, 0, 1);

    pthread_t tid[6];
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_create(&tid[0], &attr, reader, NULL);
    pthread_create(&tid[1], &attr, reader, NULL);
    pthread_create(&tid[2], &attr, reader, NULL);
    pthread_create(&tid[4], &attr, writter, NULL);
    pthread_create(&tid[5], &attr, writter, NULL);
    pthread_create(&tid[3], &attr, writter, NULL);

    for(int i = 0; i < 6; i++){
        pthread_join(tid[i], NULL);
    }

    return 0;
}